﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;

namespace FAST
{
    public enum ConflictTypes
    {
        L_MOD_R_DEL, R_MOD_L_DEL, L_R_MOD, TIME_CON
    }

    public class ConflictsCore
    {
        // Variables for objects that are passed into the class
        private List<FilesHandler> leftList = new List<FilesHandler>();
        private List<FilesHandler> rightList = new List<FilesHandler>();
        private List<int[]> leftConList = new List<int[]>();
        private List<int[]> rightConList = new List<int[]>();

        //Variables for conflict object
        private string[] conflictName = new string[] { "L modifed, R delete", "R modifed, L delete", "L and R modified", "Time Tampering" };
        private string[] latestFileAt = new string[] { "Left", "Right" };
        
        //Variables for object binding to datagrid
        private List<ConflictsObject> conList;
        

        ///Method name : ConflictsCore() : N.A for constructors.
        ///Parameters  : l_list(type List<FilesHandler>), r_list(type List<FilesHandler>), l_con(type List<int[]>), r_con(type List<int[]>)
        ///Description : An instance of the ConflictsCore constructor which stores two type List<FilesHandler> and two type List<int[]> to process information for the Conflicts User Interface.
        ///Exceptions  : None 
        public ConflictsCore(List<FilesHandler> l_list, List<FilesHandler> r_list, List<int[]> l_con, List<int[]> r_con)
        {
            this.rightConList = r_con;
            this.leftConList = l_con;
            this.leftList = l_list;
            this.rightList = r_list;
            this.conList = new List<ConflictsObject>();
        }
      
        //Method name : createConflictList() : ArrayList
        //Parameters  : None.
        //Description :  It creates conflict objects and store them in an ArrayList. The ArrayList will then be the datasource  for the datagrid.
        //Exceptions  : Nullpointer Exception, ArrayOutOfBound Exception 
        public List<ConflictsObject> createConflictList()
        {
            int count = 0;
            int leftListIndex = -1;
            int rightListIndex = -1;
            int[] leftListArr;
            int[] rightListArr;
            int conflictType;
            string alatestFileAt = "";
            string currentConflictName;

            while (count < leftConList.Count)
            {
                ConflictsObject co = new ConflictsObject();
                leftListArr = (int[])leftConList[count];
                rightListArr = (int[])rightConList[count];

                leftListIndex = (int)leftListArr[0];
                rightListIndex = (int)rightListArr[0];

                FileHandler leftFile, rightFile;
                FileInfo leftFi, rightFi;

                //Left Mod, Right Delete
                if (leftListIndex != -1 && rightListIndex == -1)
                {
                    conflictType = (int)leftListArr[1];
                    currentConflictName = conflictName[conflictType];
                    leftFile = (FileHandler)leftList[leftListIndex];
                    leftFi = leftFile.getFi();

                    //co = new ConflictsObject();
                    co.ConflictType = currentConflictName;
                    co.Filename = leftFi.Name;
                    co.LatestFile = latestFileAt[0];
                    co.LeftLocation = leftFile.getFullFilePath();
                    co.RightLocation = "NULL";
                }
                //Left Delete Right Mod
                else if (leftListIndex == -1 && rightListIndex != -1)
                {
                    conflictType = (int)rightListArr[1];
                    currentConflictName = conflictName[conflictType];
                    rightFile = (FileHandler)rightList[rightListIndex];
                    rightFi = rightFile.getFi();
                    
                    //co = new ConflictsObject();
                    co.ConflictType = currentConflictName;
                    co.Filename = rightFi.Name;
                    co.LatestFile = latestFileAt[1];
                    co.LeftLocation = "NULL";
                    co.RightLocation = rightFile.getFullFilePath();
                }
                else if (leftListIndex != -1 && rightListIndex != -1)
                {

                    conflictType = (int)leftListArr[1];
                    currentConflictName = conflictName[conflictType];

                    leftFile = (FileHandler)leftList[leftListIndex];
                    rightFile = (FileHandler)rightList[rightListIndex];
                    leftFi = leftFile.getFi();
                    rightFi = rightFile.getFi();
                    if (leftFi.LastWriteTime > rightFi.LastWriteTime)
                    {
                        alatestFileAt = latestFileAt[0];
                    }
                    else
                    {
                        alatestFileAt = latestFileAt[1];
                    }

                    //co = new ConflictsObject();
                    co.ConflictType = currentConflictName;
                    co.Filename = leftFi.Name;
                    co.LatestFile = alatestFileAt;
                    co.LeftLocation = leftFile.getFullFilePath();
                    co.RightLocation = rightFile.getFullFilePath();
                }

                conList.Add(co);
                count = count + 1;
            }
            int con = conList.Count;
            return conList;

        }

        //Method name : processConflicts() : void
        //Parameters  : count(type int), status(type int)
        //Description :  Set the status of the files in the l_list and r_list for updateReconciliation to process.
        //Exceptions  : OutOfBound Exception , NullPointer Exception
        public void processConflicts(int count, int status)
        {

            int leftListIndex = -1;
            int rightListIndex = -1;

            //Conflict object left
            int[] conObjLeft = leftConList[count];
            //Conflict object right
            int[] conObjRight = rightConList[count];

            leftListIndex = conObjLeft[0];
            rightListIndex = conObjRight[0];
           
            FileHandler leftFile, rightFile;
            FileInfo leftFi, rightFi;
            if (leftListIndex != -1 && rightListIndex == -1)
            {
                leftFile = (FileHandler)leftList[leftListIndex];
                leftFi = leftFile.getFi();

                if (status == (int)SyncActions.COPY_RIGHT)
                {
                    leftFile.setFileStatus((int)SyncActions.COPY_RIGHT);
                }
                else if (status == (int)SyncActions.COPY_LEFT)
                {
                    leftFile.setFileStatus((int)SyncActions.DELETE);
                }
                else if (status == (int)SyncActions.DEFAULT)
                {
                    leftFile.setFileStatus((int)SyncActions.DEFAULT);
                }
            }

            else if (leftListIndex == -1 && rightListIndex != -1)
            {
                rightFile = (FileHandler)rightList[rightListIndex];
                rightFi = rightFile.getFi();

                if (status == (int)SyncActions.COPY_LEFT)
                {
                    rightFile.setFileStatus((int)SyncActions.COPY_LEFT);
                }
                else if (status == (int)SyncActions.COPY_RIGHT)
                {
                    rightFile.setFileStatus((int)SyncActions.DELETE);
                }
                else if (status == (int)SyncActions.DEFAULT)
                {
                    rightFile.setFileStatus((int)SyncActions.DEFAULT);
                }

            }
            else if (leftListIndex != -1 && rightListIndex != -1)
            {

                leftFile = (FileHandler)leftList[leftListIndex];
                rightFile = (FileHandler)rightList[rightListIndex];
                leftFi = leftFile.getFi();
                rightFi = rightFile.getFi();

                if (status == (int)SyncActions.COPY_RIGHT)
                {
                    leftFile.setFileStatus((int)SyncActions.COPY_RIGHT);
                }
                else if (status == (int)SyncActions.COPY_LEFT)
                {
                    rightFile.setFileStatus((int)SyncActions.COPY_LEFT);
                }
                else if (status == (int)SyncActions.DEFAULT)
                {
                    leftFile.setFileStatus((int)SyncActions.DEFAULT);
                    rightFile.setFileStatus((int)SyncActions.DEFAULT);
                }
            }
        }
    }
}

